package edu.client;

import java.util.LinkedList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TabPanel;

import edu.client.ComprasService.ComprasService;
import edu.client.ComprasService.ComprasServiceAsync;
import edu.shared.DTO.OrdenCompraProductoDTO;

public class P_ValidarCancelarOrdenCompraProducto extends Composite {

	private static final int COL_CHECK = 0;
	private static final int COL_NROORDEN = 1;
	private static final int COL_FECHAGENERACION = 2;
	private static final int COL_PROV = 3;
	private static final int COL_MAS_INFO = 4;

	private FlexTable tablaElementosFt;

	private Constantes constante = GWT.create(Constantes.class);

	private Button validarOrdenesBtn;
	private Button cancelarOrdenesBtn;

	// variables de lógica
	TabPanel padre;
	List<OrdenCompraProductoDTO> ordenesCompraProductoDTO;

	public P_ValidarCancelarOrdenCompraProducto(TabPanel padre) {

		// inicialización de variables de lógica
		this.padre = padre;
		
		LayoutPanel layoutPanel = new LayoutPanel();
		initWidget(layoutPanel);		
		layoutPanel.setSize((Window.getClientWidth() - 55) + "px", "452px");
				
		Label lblOrdenes = new Label("ÓRDENES DE COMPRA DE PRODUCTOS");
		lblOrdenes.setStyleName("labelTitulo");
		layoutPanel.add(lblOrdenes);
		layoutPanel.setWidgetLeftWidth(lblOrdenes, 2.5, Unit.PCT, 95.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(lblOrdenes, 15.0, Unit.PX, 50.0, Unit.PX);
		
		ScrollPanel spOrdenes = new ScrollPanel();
		spOrdenes.setStyleName("tabla");
		layoutPanel.add(spOrdenes);
		layoutPanel.setWidgetLeftWidth(spOrdenes, 5.0, Unit.PCT, 90.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(spOrdenes, 85.0, Unit.PX, 250.0, Unit.PX);	
		
		tablaElementosFt = new FlexTable();
		spOrdenes.setWidget(tablaElementosFt);
		tablaElementosFt.setSize("100%", "100%");

		// columnas de la tabla
		//checkbox de seleccion
		tablaElementosFt.setText(0, COL_CHECK, "");
		tablaElementosFt.getCellFormatter().setWidth(0, COL_CHECK, "5%");
		
		// N° orden compra
		tablaElementosFt.setText(0, COL_NROORDEN, constante.nroOrdenCompra());
		tablaElementosFt.getCellFormatter().setWidth(0, COL_NROORDEN, "20%");

		// fecha de generación
		tablaElementosFt.setText(0, COL_FECHAGENERACION, constante.fechaGeneracion());
		tablaElementosFt.getCellFormatter().setWidth(0, COL_FECHAGENERACION, "30%");

		// proveedor
		tablaElementosFt.setText(0, COL_PROV, constante.proveedor());
		tablaElementosFt.getCellFormatter().setWidth(0, COL_PROV, "35%");

		// más información
		tablaElementosFt.setText(0, COL_MAS_INFO, constante.masInformacion());
		tablaElementosFt.getCellFormatter().setWidth(0, COL_MAS_INFO, "10%");

		// seteamos el estilo a los encabezados
		tablaElementosFt.getRowFormatter().addStyleName(0, "tablaEncabezado");
		
		Label lblPie = new Label("");
		lblPie.setStyleName("labelTitulo");
		layoutPanel.add(lblPie);
		layoutPanel.setWidgetLeftWidth(lblPie, 2.5, Unit.PCT, 95.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(lblPie, 335.0, Unit.PX, 50.0, Unit.PX);

		Button salirBtn = new Button("CANCELAR");
		layoutPanel.add(salirBtn);
		layoutPanel.setWidgetRightWidth(salirBtn, 5.0, Unit.PCT, 10.0, Unit.PCT);
		layoutPanel.setWidgetBottomHeight(salirBtn, 15.0, Unit.PX, 28.0, Unit.PX);
		
		salirBtn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				salir(event);
			}
		});

		validarOrdenesBtn = new Button("VALIDAR");
		layoutPanel.add(validarOrdenesBtn);
		layoutPanel.setWidgetRightWidth(validarOrdenesBtn, 17.5, Unit.PCT, 10.0, Unit.PCT);
		layoutPanel.setWidgetBottomHeight(validarOrdenesBtn, 15.0, Unit.PX, 28.0, Unit.PX);
		
		validarOrdenesBtn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				
				validarOrdenesBtn.setEnabled(false);
				
				validarOrdenes();
			}
		});
		
		cancelarOrdenesBtn = new Button("DESCARTAR");
		layoutPanel.add(cancelarOrdenesBtn);
		layoutPanel.setWidgetRightWidth(cancelarOrdenesBtn, 30.0, Unit.PCT, 10.0, Unit.PCT);
		layoutPanel.setWidgetBottomHeight(cancelarOrdenesBtn, 15.0, Unit.PX, 28.0, Unit.PX);
		
		cancelarOrdenesBtn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				
				cancelarOrdenesBtn.setEnabled(false);
				
				cancelarOrdenes();
			}
		});
		
		// cargamos la tabla con las órdenes de compra de producto
		cargarOrdenes();
	}

	public void salir(ClickEvent event) {
		padre.remove(Validaciones.numeroElemento(padre, "VALIDAR ORDEN COMPRA PRODUCTO"));
	}

	/**
	 * Método que carga las órdenes de compra de producto a validar/cancelar
	 */
	public void cargarOrdenes() {

		ComprasServiceAsync comprasService = GWT.create(ComprasService.class);

		comprasService.buscarOrdenesCompraProducto("GENERADA", new AsyncCallback<List<OrdenCompraProductoDTO>>() {

			@Override
			public void onSuccess(List<OrdenCompraProductoDTO> result) {
				cargarTabla(result);
				cancelarOrdenesBtn.setEnabled(true);
				validarOrdenesBtn.setEnabled(true);
			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("ERROR EN EL SERVICIO");
				cancelarOrdenesBtn.setEnabled(true);
				validarOrdenesBtn.setEnabled(true);
			}
		});
	}

	public void cargarTabla(List<OrdenCompraProductoDTO> ordenes) {

		// inicializamos la lista de compra para futuras modificaciones
		this.ordenesCompraProductoDTO = ordenes;

		//borramos todas las filas de la tabla
		for(int i = tablaElementosFt.getRowCount(); i > 1; i--)
			tablaElementosFt.removeRow(i-1);
		
		// identifica una fila unívocamente
		int item = 1;

		for (OrdenCompraProductoDTO orden : ordenes) {

			// imágen más información
			Label info = new Label("");
			info.setSize("16px", "16px");
			info.setStyleName("labelInfo");

			//seteamos el formato a la fecha
			DateTimeFormat fmtDate = DateTimeFormat.getFormat("dd/MM/yyyy");
			String fecha = fmtDate.format(orden.getFechaGeneracion());

			// cargamos una fila de la tabla
			//checkbox de seleccion
			tablaElementosFt.getFlexCellFormatter().setHorizontalAlignment(item, COL_CHECK, HasHorizontalAlignment.ALIGN_CENTER);			
			tablaElementosFt.setWidget(item, COL_CHECK, new CheckBox());
			
			// columna nro. orden
			tablaElementosFt.setWidget(item, COL_NROORDEN, new Label(String.valueOf(orden.getIdOrden())));
			tablaElementosFt.getCellFormatter().setWordWrap(item, COL_NROORDEN, true);

			// columna fecha generación
			tablaElementosFt.setWidget(item, COL_FECHAGENERACION, new Label(fecha));
			tablaElementosFt.getCellFormatter().setWordWrap(item, COL_FECHAGENERACION, true);

			// columna proveedor
			tablaElementosFt.setWidget(item, COL_PROV, new Label(orden.getProveedor()));
			tablaElementosFt.getCellFormatter().setWordWrap(item, COL_PROV, true);

			// columna más información
			tablaElementosFt.setWidget(item, COL_MAS_INFO, info);
			tablaElementosFt.getFlexCellFormatter().setHorizontalAlignment(item, COL_MAS_INFO, HasHorizontalAlignment.ALIGN_CENTER);

			// seteamos el estilo de renglón de tabla
			tablaElementosFt.getRowFormatter().setStyleName(item, "tablaRenglon");

			info.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {

					//obtenemos la celda en donde se hizo click
					Cell celda = tablaElementosFt.getCellForEvent(event);
					
					//obtenemos la orden de compra. Restamos 1 al row index porque la fila 1 es el encabezado
					OrdenCompraProductoDTO orden = ordenesCompraProductoDTO.get(celda.getRowIndex() - 1);
					
					P_DetalleOrdenCompraProducto pDetalleOrden = new P_DetalleOrdenCompraProducto(orden.getIdOrden(), false);
					pDetalleOrden.setGlassEnabled(true);
					pDetalleOrden.center();
					pDetalleOrden.show();
				}
			});

			item++;
		}
	}
	
	
	/**
	 * Método que valida las órdenes de compra seleccionadas
	 */
	public void validarOrdenes()
	{		
		//buscamos las órdenes seleccionadas
		List<Integer> ordenesAValidar = ordenesSeleccionadas();
		
		//si se seleccionó al menos una orden
		if(ordenesAValidar.size() > 0)
		{
			//validamos las órdenes de compra de productos
			ComprasServiceAsync comprasService = GWT.create(ComprasService.class);
	
			comprasService.validarOrdenesCompraProducto(ordenesAValidar, new AsyncCallback<Boolean>() {
	
				@Override
				public void onSuccess(Boolean result) {
					//AL VALIDAR LAS ÓRDENES DE MANERA EXITOSA, SE DEBEN PASAR LOS PRODUCTOS COMPRADOS A DISPONIBLES EN TRÁNSITO EN INVENTARIO.
					if(result){
						Window.alert("Las órdenes seleccionadas han sido validadas de manera exitosa");
					}
					
					else
						Window.alert("No se ha podido validar las órdenes seleccionadas");
					
					//volvemos a cargar las órdenes en la tabla
					cargarOrdenes();
				}
	
				@Override
				public void onFailure(Throwable caught) {
					Window.alert("ERROR EN EL SERVICIO");
					validarOrdenesBtn.setEnabled(true);
				}
			});
		}
		
		//si no se seleccionaron órdenes
		else{
			Window.alert("Seleccione al menos una orden de compra.");
			validarOrdenesBtn.setEnabled(true);
		}
		
	}
	
	
	/**
	 * Método que cancela las órdenes de compra seleccionadas
	 */
	public void cancelarOrdenes()
	{		
		//buscamos las órdenes seleccionadas
		List<Integer> ordenesACancelar = ordenesSeleccionadas();	
		
		//si se seleccionó al menos una orden
		if(ordenesACancelar.size() > 0)
		{
			//cancelamos las órdenes de compra de productos
			ComprasServiceAsync comprasService = GWT.create(ComprasService.class);
	
			comprasService.cancelarOrdenesCompraProducto(ordenesACancelar, new AsyncCallback<Boolean>() {
	
				@Override
				public void onSuccess(Boolean result) {
					if(result){
						Window.alert("Las órdenes seleccionadas han sido canceladas de manera exitosa");
					}
					
					
					else{
						Window.alert("No se ha podido cancelar las órdenes seleccionadas");						
					}
					
					//volvemos a cargar las órdenes en la tabla
					cargarOrdenes();
					
				}
	
				@Override
				public void onFailure(Throwable caught) {
					Window.alert("ERROR EN EL SERVICIO");
					cancelarOrdenesBtn.setEnabled(true);
				}
			});
		}
		
		//si no se seleccionaron órdenes
		else{
			Window.alert("Seleccione al menos una orden de compra.");
			cancelarOrdenesBtn.setEnabled(true);	
		}
		
	}
	
	
	/**
	 * Método que devuelve los id de las órdenes de compra de productos correspondientes a las filas seleccionadas
	 * @return. Devuelve una lista con los id de las órdenes seleccionadas.
	 */
	public List<Integer> ordenesSeleccionadas()
	{
		List<Integer> ordenesSeleccionadas = new LinkedList<Integer>();
		
		//recorremos las filas de la tabla para obtener las que fueron seleccionadas
		for(int i=1; i< tablaElementosFt.getRowCount(); i++){
			
			//buscamos el checkbox en la tabla
			CheckBox checkbox = (CheckBox) tablaElementosFt.getWidget(i, COL_CHECK);
			
			if(checkbox.getValue() == true)
			{
				//buscamos el id de la orden de compra. Se utiliza i-1 ya que las columnas se identifican a partir de 1 en vez de 0
				ordenesSeleccionadas.add(ordenesCompraProductoDTO.get(i-1).getIdOrden());
			}			
		}
		
		return ordenesSeleccionadas;
	}
}
